MedicalImaging笔记(X1) FoDicom传输(一)Scp和Scu

PACS Components

DICOM - Digital Imaging and Communication in Medicine
PACS - Picture Archiving and Communication System

Fodicom的Sample分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Sample Project: C-Store SCP
var server = DicomServer.Create<CStoreSCP>(port);//启动了监听

//Sample Project: ConsoleTest
var client = new DicomClient();
client.NegotiateAsyncOps();
for (int i = 0; i < 10; i++)
{
client.AddRequest(new DicomCEchoRequest());
}

client.AddRequest(new DicomCStoreRequest(@"test1.dcm"));
client.AddRequest(new DicomCStoreRequest(@"test1.dcm") {
OnResponseReceived = (DicomCStoreRequest req, DicomCStoreResponse rsp) => {
Console.WriteLine("{0}: {1}", req.SOPInstanceUID, rsp.Status);
}
});

client.Send("127.0.0.1", 11112, false, "SCU", "STORESCP"); // Client是在Send的时候才加入的ip地址和端口

DicomServer和DicomClient的类图结构如下:

Server端叫做Service Class Provider, Client端叫做Service Class User, 二者之间建立连接, 叫做Association

在DCMTK中, 传DICOM到工作站和PACS用的程序是storescp.exe和storescu.exe

二者之间通信分为3层:

  1. socket
  2. Association(Accept,Release等, 术语叫做ACSE, Association Control Service Element)
  3. Command(Find, Store等Command, 术语叫做DIMSE, DICOM Message Service Element)

具体的收发包由DicomService完成, DicomService和IDicomService没有直接联系

DicomServer的创建

CStoreSCP就是类图中的T, T除了继承DicomService和IDicomServiceProvider的通用接口外, 还需要实现特有Service的接口. CStoreSCP的类图如下:

如此, DicomServer就能够提供Echo服务和Store服务; 需要说明的是CStoreSCP是样例中实现的, FoDicom本身没有提供;FoDicom只给出了DicomCEchoProvider的实现, 其他类型的服务只是给出了接口, 具体实现交由业务去做

Client端

client.AddRequest(new DicomCEchoRequest());
client.AddRequest(new DicomCStoreRequest(@”test1.dcm”));

DicomCEchoRequest和DicomCStoreRequest属于Command
DicomCEchoRequest和DicomCStoreRequest相关的类图如下:

DicomMessage中包含Command和Dataset. DIMSE分为2类:
DIMSE-N: those services applicable to Normalized(普通的) SOP Instances
DIMSE-C: those services applicable to Composite(复合的) SOP Instances

DIMSE-N服务其中一个应用是DICOM打印, 常用的是DIMSE-C服务.

DIMSE-C服务介绍

C-Echo: Ping

C-Store: 传DICOM到PACS归档

C-Find: 查询病人的信息

C-Get: 获取病人的DICOM, C-Get blends C-Find and C-Store into a single service class

C-Move: 将一个PACS上的DICOM移动到另一个地方, 也是复合操作

除了C-Echo和C-Store有样例外, FoDicom没有提供其他几个SCP的具体实现;

C-Get SCP的实现参考:
http://blog.csdn.net/zssureqh/article/details/50334735

C-FIND and C-MOVE SCP的实现参考:
http://blog.csdn.net/zssureqh/article/details/41631563

Client的Send方法

client.Send(“127.0.0.1”, 11112, false, “SCU”, “STORESCP”);

  1. 构造NetworkStream
  2. 构造DicomAssociation
  3. DoSendAsync(networkstream, dicomassociation)

DoSendAsync是DicomClient的重点

  1. 构造DicomServiceUser
  2. SendRequest(request)
构造DicomServiceUser

DicomServiceUser的构造方法中, 调用SendAssociationRequest(association), 进行与Server端的连接
SendAssociationRequest调用SendPDUAsync(new AAssociateRQ(Association));

这里出现PDUAAssociateRQ

PDU和AAssociateRQ的类图如下:

AAssociateRQ是PDU的一种, PDU叫做Protocol Data Unit

  1. A-Associate-RQ PDU: requests DICOM association.
  2. A-Associate-AC PDU: accepts DICOM association.(in response to A-Associate-RQ).
  3. A-Associate-RJ PDU: rejects DICOM association. (in response to A-Associate-RQ).
  4. P-Data-TF PDU: transfers a block of DICOM data.
  5. A-Release-RQ PDU: requests association termination (release).
  6. A-Release-RP PDU: responds to an association termination request(release).
  7. A-Abort PDU: aborts any invalid association

Use of Dicom PDUs

其中P-Data-TF is different from the other PDU types we just considered; it is the only type responsible for transmitting the actual data. P-Data-TF sends our DICOM objects, cut into chunks known as “Protocol Data Value” (PDV) items. 前面介绍的DIMSE是以P-Data-TF类型的PDU进行传输的

上面介绍的是1.构造DicomServiceUser
接下来介绍2. SendRequest(request)
SendRequest涉及到DicomService, 比较复杂, 见FODICOM传输笔记(二)